#include "stdafx.h"
#include "Link.h"
#include "Http2.h"

#pragma comment(lib,"Winhttp.lib")

Http2::Http2(PTSTR agent){
	name=0;
	port=INTERNET_DEFAULT_HTTP_PORT;
	req=0;
	connect=0;
	session=WinHttpOpen(agent,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
		WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);
	if(session){
		Http2* p=this;
		WinHttpSetOption(session,WINHTTP_OPTION_CONTEXT_VALUE,&p,sizeof(p));
		WinHttpSetStatusCallback(session,callback,
			WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,NULL);
	}else throw(0);
}
Http2::~Http2(void){
	if(connect)
		WinHttpCloseHandle(connect);
	if(session)
		WinHttpCloseHandle(session);
}

void CALLBACK Http2::callback(HINTERNET session,DWORD_PTR context,DWORD status,
	LPVOID info,DWORD length){
	Http2* p=(Http2*)context;
	if(p)
		p->onCallback(session,status,info,length);
}
Bin* Http2::exec(PTSTR verb,PTSTR name,int port,PTSTR location,void* contents,
				 uint contentsLen){
	connect=WinHttpConnect(session,name,port,0);
	if(connect){
		req=WinHttpOpenRequest(connect,verb,location,NULL,
			WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,0);
		if(req){
			BOOL r=WinHttpSendRequest(req,WINHTTP_NO_ADDITIONAL_HEADERS,0,
				contents,contentsLen,contentsLen,0);
			if(r){
				r=WinHttpReceiveResponse(req,NULL);
				if(r){
					uint len=0;
					Link *link=new Link();
					do{
						if(WinHttpQueryDataAvailable(req,&len)&&len){
							if(void *buf=malloc(len)){
								uint ded;
								if(WinHttpReadData(req,buf,len,&ded))
									link->append(buf,ded);
								free(buf);
							}
						}
					}while(len>0);
					uint n=link->comp(0);
					ubyte *d=(ubyte*)malloc(n);
					if(d){
						link->comp(d);
						WinHttpCloseHandle(req);
						req=0;
						return new Bin(d,n);
					}
				}
			}
		}
	}
	throw(0);
}
Bin* Http2::get(PTSTR location){
	return exec(L"GET",name,port,location,WINHTTP_NO_REQUEST_DATA,0);
}
void Http2::onCallback(HINTERNET inernet,uint status,LPVOID info,uint length){
}
/*uint Http2::status(HINTERNET req){
	uint len=0;
	WinHttpQueryHeaders(req,WINHTTP_QUERY_STATUS_CODE,
		WINHTTP_HEADER_NAME_BY_INDEX,NULL,&len,WINHTTP_NO_HEADER_INDEX);
	if(len){
		if(PTSTR s=(TCHAR*)malloc(len)){
			WinHttpQueryHeaders(req,WINHTTP_QUERY_STATUS_CODE,
				WINHTTP_HEADER_NAME_BY_INDEX,s,&len,
				WINHTTP_NO_HEADER_INDEX);
			uint res;
			swscanf_s(s,L"%d",&res);
			free(s);
			return res;
		}
	}
	return 0;
}*/
Bin* Http2::put(PTSTR location,void* contents,uint contLen){
	return exec(L"PUT",name,port,location,contents,contLen);
}